package com.bigdata

object Demo15List {

  def main(args: Array[String]): Unit = {
    /**
     * scala集合
     * 1、List: 有序，不唯一
     * 2、Set ：无序，唯一
     * 3、Map: kv格式   key是唯一的
     * 4、Tuple: 元组，固定长度集合
     */

    /**
     * List集合
     * scala的集合比java的集合好用-多了很多的方法
     */
    //不可变的List，不可以增加删除元素以及修改元素
    val list: List[Int] = List[Int](1, 2, 3, 5, 3, 1, 2, 8)


    // 通过下标获取数据
    val num: Int = list(2)
    println(num)

    //获取第一个元素
    println(list.head)

    //获取最后一个元素
    println(list.last)

    //获取不包含第一个元素的所有的元素
    println(list.tail)

    //将集合中的元素拼接成一个字符串
    println(list.mkString("-"))

    //反转，返回一个新的List
    println(list.reverse)

    //取前n个元素
    val subList: List[Int] = list.take(3)
    println(subList)

    //取后n个元素
    println(list.takeRight(3))

    //去重
    println(list.distinct)

    // 间接的实现了去重
    println(list.toSet)

    //求和，集合元素的类型必须是可以求和的类型
    println(list.sum)
    //取最大值
    println(list.max)
    //最小值
    println(list.min)

    println("=" * 100)

    /**
     * foreach: 循环集合，将集合中的元素一个一个传递给后面的函数，foreach没有返回值
     *
     */
    //    for (num <- list) {
    //      println(num)
    //    }
    list.foreach(println)

    var sum = 0
    for (num <- list) {
      sum += num
    }
    println(sum)

    println("=" * 100)

    /**
     * 给每个元素加一（处理集合中的元素）,处理之后的结果存入到一个新的List中
     * 在写scala代码的时候，要尽量的避免使用while、for循环
     */
    /**
     * map:循环集合将集合中的元素一个一个传递给后面的函数，函数的返回值会构建出一个新的集合
     * i代表的是集合中所有的元素
     */
    //    val addList: List[Int] = list.map((num: Int) => {
    //      num + 1
    //    })
    val addList: List[Int] = list.map(_ + 1)
    println(addList)

    /**
     * 处理集合中的元素，偶数加1，奇数乘以2
     */
    val mapList: List[Int] = list.map(num => {
      if (num % 2 == 0) { // 偶数
        num + 1
      } else { // 奇数
        num * 2
      }
    })
    println(mapList)

    /**
     * foreach 函数，把list中的每一项传递到函数中
     * foreach 函数中还需要传递一个函数，这个函数的参数就是list中的每一项的值
     * 我们需要传递一个函数来指定这个值怎么处理，一般会传递一个lambda表达式的函数
     */
    //    list.foreach((num:Int) => {
    //      println(num)
    //    })

    list.foreach(println)

    /**
     * 取出集合中奇数
     * Filter: 循环集合，将集合中的元素一个一个传递给后面的函数
     * 如果函数返回true保留数据，如果函数返回false过滤数据
     * 只保留list集合中奇数
     */
    //    val filterList: List[Int] = list.filter((num: Int) => {
    //      // 如果是奇数返回true，偶数返回false
    //      // 返回true这个值会保留，返回false值会被过滤掉
    //      num % 2 == 1
    //    })

    val filterList: List[Int] = list.filter(_ % 2 == 1)
    println(filterList)

    println("=" * 100)

    /**
     * 将一行中的多个单词拆分出来，一个单纯一行
     * 调用flatmap方法，也会把list中的每一项值传递到函数中，也会定义一个lambda表达式来处理这个值
     * 和之前不同的是这个lambda函数的返回值要求是一个集合
     * 最终flatmap的返回值是一个集合，集合中的值就是lambda返回的集合中的所有的值来组成的
     */
    val linesList = List("java,spark,hadoop", "datax,scala,java", "hadoop,hive,sqoop")

    //    val words: List[String] = linesList.flatMap(line => {
    //      line.split(",")
    //    })

    val words: List[String] = linesList.flatMap(_.split(","))

    words.foreach(println)

    println("=" * 100)

    /**
     * 多集合排序
     * 如果返回的正数那么就是正序，如果返回的是负数就是倒序
     * sortBy: 需要指定一个排序的字段，默认是升序
     * sortWith: 指定一个排序的比较规则
     */
    val list3: List[Int] = List(1, 2, 3, 4, 6, 4, 4, 2, 1, 1, 2, 3, 4, 2, 32, 4, 5, 6)
    // 想要使用num进行排序，匿名函数的参数就是list中的值，函数的返回值是排序的字段
    // 默认是升序
    val sortList: List[Int] = list3.sortBy(num => -num)
    println(sortList)

    val sortWithList: List[Int] = list3.sortWith((x, y) => {
      x > y // 倒序
      y > x // 正序
    })

    println(sortWithList)

    println("=" * 100)

    /**
     * groupBy: 分组，需要指定一个分组的字段
     * key => value
     * java => [java, java, java]
     * spark => [spark, spark]
     * hadoop => [hadoop]
     */
    val ws = List("java", "spark", "java", "java", "spark", "jayy", "jaxx", "spaaa", "hadoop")
    val wordGroup: Map[String, List[String]] = ws.groupBy((word: String) => {
      // 返回的是分组的key
      word.substring(0, 2)
    })

    wordGroup.foreach(println)

    // 统计wordcount, map讲完
    wordGroup.map((kv: (String, List[String])) => {

    })


    /**
     * 以下所有的方法都是返回新的集合，不会修改原始的集合
     * 同时以下这些方法在set集合中也有，除了sort
     * foreach:遍历数据
     * map：一条一条处理数据
     * filter：过滤数据
     * flatMap:将一行转换成多行
     * sortBy：排序
     * groupBy：分组
     */


  }

}
